﻿using System;
using System.Collections.Generic;
using Snmp.Agent.DataLoader;
using Snmp.Agent.MplsLsrMib;
using SnmpWorkshop.Communication;
using SnmpWorkshop.Tools;

using Lextm.SharpSnmpLib;
using Lextm.SharpSnmpLib.Messaging;

namespace SnmpWorkshop.SnmpAgent
{
    public class SnmpAgent : SnmpAgentBase
    {
        private Mib mib = new Mib();
        protected void snmpMessagePrint(ISnmpPdu _pdu)
        {
            string text = String.Format("\ntype: {0}\n requestId: {1}\n errorStatus: {2}\n errorIndex: {3}\n", _pdu.TypeCode, _pdu.RequestId, _pdu.ErrorStatus, _pdu.ErrorIndex);

            foreach (Variable variable in _pdu.Variables)
            {
                text += variable.Id.ToString() + "\n";
            }

            HandyLogClient.Write("snmpMessagePrint", text);
        }

        protected override void snmpMessageHandler(ISnmpMessage _message)
        {


            HandyLogClient.Write("SmpnAgent", String.Format("snmp message received", _message));

            ISnmpPdu pdu = _message.Pdu();

            this.snmpMessagePrint(pdu);
            var variableList = new List<Variable>();
            switch (pdu.TypeCode)
            {
                case SnmpType.GetRequestPdu:
                    foreach (var variable in _message.Variables())
                    {
                        if(variable.Id.ToString().StartsWith(Mib.MplsLsrStdMibId))
                        {
                            variableList.Add(mib.GetRequest(variable.Id.ToString()));
                        }
                        else
                        {
                            variableList.Add(new Variable(variable.Id, new NoSuchObject()));
                        }
                    }  
                    break;
                case SnmpType.GetNextRequestPdu:
                    foreach (var variable in _message.Variables())
                    {
                       variableList.Add(mib.GetNextRequest(variable.Id.ToString()));
                    }
                    break;
                case SnmpType.GetBulkRequestPdu:
                    foreach (var variable in _message.Variables())
                    {
                        if (variable.Id.ToString().StartsWith(Mib.MplsLsrStdMibId))
                        {
                            int maxRepetitions = _message.Pdu().ErrorIndex.ToInt32();
                            //int nonRepeaters = _message.Pdu().ErrorStatus.ToInt32();
                            if(maxRepetitions>0)
                            {
                                Variable firstVar = mib.GetRequest(variable.Id.ToString());
                                if(firstVar.Data is NoSuchObject)
                                {
                                    firstVar = mib.GetNextRequest(variable.Id.ToString());
                                }
                                variableList.Add(firstVar);
                            }
                            for(int i = 1;i<maxRepetitions;i++)
                            {
                                variableList.Add(mib.GetNextRequest(variableList[variableList.Count-1].Id.ToString()));
                            }
                        }
                        else
                        {
                            variableList.Add(new Variable(variable.Id, new NoSuchObject()));
                        }
                    }
                    break;
				case SnmpType.SetRequestPdu:
		            foreach (var variable in _message.Variables())
		            {
						if (variable.Id.ToString().StartsWith(Mib.MplsLsrStdMibId))
						{
							variableList.Add(mib.GetNextRequest(variable.Id.ToString()));
						}
						else
						{
							variableList.Add(new Variable(variable.Id, new NoSuchObject()));
						}
		            }
                    break;
            }

            var responseMessage = new ResponseMessage(_message.RequestId(), _message.Version, _message.Community(), ErrorCode.NoError, 0, variableList);
            this.sendSnmpMessage(responseMessage);
        }
    }
}